package cate.game.role.farm.udgpalace;

import cate.common.table.d.GDFight;
import cate.common.table.d.GDFunc;
import cate.common.table.d.GDHoardTask;
import cate.common.table.d.GDUdgPalace;
import cate.common.table.item.hero.row.HeroBaseRow;
import cate.common.util.GameResult;
import cate.game.play.proce.play.PlayPO;
import cate.game.role.Role;
import cate.game.role.bag.hero.Hero;
import cate.game.role.farm.AbstractFarm;
import cate.game.role.farm.udgpalace.msg.UdgPalaceDataResp;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;

import java.util.*;

@NoteClass("我的地宫探险数据")
public class MyUdgPalace extends AbstractFarm {
    @NoteField("第几轮")
    public int weekNo;

    @NoteField("当前关卡数据")
    public UdgPalaceLevel level;

    @NoteField("我的地宫探险队伍")
    public UdgPalaceTeam team;

    @NoteField("任务数据")
    public UdgPalaceTask task;

    @NoteField("是否特殊")
    public boolean special;

    @JsonIgnore
    @NoteField("是否已记录灵界秘藏任务")
    public boolean ifHoard;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (level == null) {
            level = new UdgPalaceLevel();
        }
        level.initialize(role);
        if (team == null) {
            team = new UdgPalaceTeam();
        }
        team.initialize(role);
        if (task == null) {
            task = new UdgPalaceTask();
        }
        task.initialize(role);
    }

    @Override
    public void onEnter() {
        super.onEnter();
        checkReset(true);
    }

    /**
     * 检测是否要构建地图
     */
    private synchronized void checkReset(boolean silence) {
        if (!isOpen()) {
            return;
        }
        int currentWeekNo = role.getGame().farm.local.udgPalace.data.weekNo;
        // 开启了新的一期
        if (this.weekNo != currentWeekNo) {
            this.weekNo = currentWeekNo;
            reset();
            if (!silence) {
                noticeUpdate();
            }
        }
    }

    @Override
    public int getFuncId() {
        return GDFunc.UDG_PALACE;
    }

    @Override
    public void onAfterOpen() {
        checkReset(false);
    }

    @Override
    public void onDaySpan(boolean silence) {
        checkReset(silence);
    }

    public void reset() {
        team.reset();
        level.reset();
        task.reset();
        special = false;
        ifHoard = false;
    }

    public GameResult<Void> setTeam(List<String> heroUids) {
        GameResult<Void> r = new GameResult<>();
        if (!isOpen()) {
            return r.fail("功能未开启");
        }
        if (heroUids == null || heroUids.size() > GDUdgPalace.POSITION_HERO_NUM) {
            return r.fail("错误的阵容");
        }
        Set<Integer> protos = new HashSet<>();
        List<Hero> heros = new ArrayList<>();
        for (String heroUid : heroUids) {
            Hero hero = role.getBag().hero.getItem(heroUid);
            if (hero == null) {
                return r.fail("英雄不存在");
            }
            HeroBaseRow baseRow = hero.getTpl(role.getGame());
            if (baseRow == null) {
                return r.fail("英雄不存在");
            }
            if (protos.contains(baseRow.protoId)) {
                return r.fail("不可重复上阵同一个英雄");
            }
            protos.add(baseRow.protoId);
            heros.add(hero.copy());
        }
        r = team.setTeam(heros);
        if (!r.ok()) {
            return r;
        }
        noticeUpdate();
        return r;
    }

    public GameResult<Void> challenge(String heroUid, int bossId, boolean skip, boolean special) {
        GameResult<Void> r = new GameResult<>();
        if (!isOpen()) {
            return r.fail("功能未开启");
        }
        Hero hero = team.getHero(heroUid);
        if (hero == null) {
            return r.fail("食灵不存在");
        }
        if (team.heroIsDead(hero.uid)) {
            return r.fail("食灵已经阵亡拉");
        }
        r = level.vsBoss(bossId, hero, team.getHpExtend(), skip || special, special);
        if (!r.ok()) {
            return r;
        }
        this.special = special;
        if (!skip) {
            startFighting();
        }
        return r;
    }

    public void noticeUpdate() {
        role.sendNow(new UdgPalaceDataResp(this));
    }

    public GameResult<Void> killBoss(int bossId) {
        GameResult<Void> r = level.killBoss(bossId);
        if (!r.ok()) {
            return r;
        }
        task.afterChallenge(true);
        return r;
    }

    public GameResult<Void> killAllBoss() {
        GameResult<Void> r = new GameResult<>();
        GameResult<Integer> killRes = level.killAllBoss();
        if (!killRes.ok()) {
            return r.fail(killRes);
        }
        for (int i = 0; i < killRes.data; ++i) {
            task.afterChallenge(true);
        }
        return r;
    }

    public void afterChallenge(int bossId, PlayPO play, boolean autoHandleEvent) {
        boolean win = play.winner == GDFight.Team.A;
        task.afterChallenge(win);
        team.afterChallenge(play.teamEnd.a);
        level.afterChallenge(bossId, win, play.teamEnd.b);
        if (autoHandleEvent) {
            level.autoHandleEvent();
        }
        if (!ifHoard) {
            boolean check = role.getRes().hoard.addition.addTask(GDHoardTask.UDG_PALACE);
            this.ifHoard = check;
        }
        noticeUpdate();
    }

    public GameResult<Void> handlePosEvent(int pos, int chooseId) {
        return level.handlePosEvent(pos, chooseId, true);
    }

    public GameResult<Void> useItem(int itemId, String heroUid, int bossId) {
        GameResult<Void> r = team.useItem(itemId, heroUid, bossId);
        if (r.ok()) {
            noticeUpdate();
        }
        return r;
    }

    public GameResult<Void> buyShopItem(String itemUid) {
        GameResult<Void> r = team.buyItem(itemUid);
        if (r.ok()) {
            noticeUpdate();
        }
        return r;
    }

    public GameResult<Void> getTaskReward(int tid) {
        return task.getReward(tid);
    }

    @Override
    public int getFightFuncId() {
        return getFuncId();
    }
}
